home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / ffuncs1.arc / GETF.C < prev    next >
C/C++ Source or Header  |  1988-09-02  |  7KB  |  205 lines

  1. /* GETF.C - locate the source file containing a specified function and
  2. *           present it in your favorite editor.
  3. * Copyright (c) 1988 Marvin Hymowech
  4. */
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9.  
  10. #define LINT_ARGS
  11.  
  12. #define TRUE       1
  13. #define FALSE      0
  14. #define LINE_LEN 256
  15.  
  16.    /* function declarations */
  17. int patn_match(char *, char *);
  18. void edit(char *, char *);
  19. void ask_for_file(char **, char **, unsigned int);
  20.  
  21. unsigned int num_ctl_patns;      /* number of %s symbols in GETFEDIT var */
  22. char *file_token, *func_token;
  23. char arg1[64];                   /* argument for editor command line */
  24. char *arg1_ctl;                  /* ctl string for building arg1 */
  25. char *pgm_name;                  /* name of editor to invoke */
  26.  
  27. main(argc, argv)
  28. int argc;
  29. char **argv;
  30. {
  31.  
  32.    #define MAX_CHOICES 256
  33.  
  34.    char file_line[LINE_LEN], func_line[LINE_LEN];
  35.    char func_name[64], edit_cmd[128];
  36.    char *env_edit_cmd, *ctl_patn;
  37.    unsigned int last_func, len, eof = FALSE;
  38.    static char file_name[] = "FUNCS.TXT";       /* input file name */
  39.    FILE *funcs_file;
  40.    static char delim[] = "\n\t ";      /* white space delimiters */
  41.    unsigned int num_choices = 0;
  42.    char *func_choices[MAX_CHOICES], *file_choices[MAX_CHOICES];
  43.  
  44.    if (argc != 2) {
  45.       fprintf( stderr, "\ngetf: wrong number of arguments");
  46.       exit(1);
  47.    }
  48.  
  49.          /* the argument is the function name to find */
  50.    strcpy( func_name, *++argv);
  51.  
  52.    if ( (env_edit_cmd = getenv( "GETFEDIT")) == NULL) {
  53.       fprintf( stderr, "\ngetf: missing environment variable GETFEDIT");
  54.       exit(1);
  55.    }
  56.  
  57.          /* Check if GETFEDIT environment variable has a place for
  58.          *  function name as well as file name - note function name
  59.          *  is assumed to go in the first %s pattern if there are
  60.          *  two %s patterns.
  61.          */
  62.  
  63.    if ( (ctl_patn = strstr(env_edit_cmd, "%s")) == NULL) {
  64.       fprintf( stderr,
  65.             "\ngetf: environment variable GETFEDIT has no %%s pattern");
  66.       exit(1);
  67.    }
  68.  
  69.    num_ctl_patns = strstr(++ctl_patn, "%s") == NULL ? 1 : 2;
  70.    strcpy( edit_cmd, env_edit_cmd);
  71.    if( (pgm_name = strtok( edit_cmd, " ")) == NULL) {
  72.       fprintf( stderr,
  73.             "\ngetf: environment variable GETFEDIT has incorrect format.");
  74.       exit(1);
  75.    }
  76.  
  77.          /* point to argument following program name */
  78.    arg1_ctl = edit_cmd + strlen(pgm_name) + 1;
  79.    if( (funcs_file = fopen(file_name, "r")) == NULL) {
  80.       fprintf(stderr, "\ngetf: can't open %s\n", *argv);
  81.       exit(1);
  82.    }
  83.  
  84.    while ( !eof) {      /* loop thru file names, which end with colon */
  85.       if (fgets(file_line, LINE_LEN, funcs_file) == NULL)
  86.          break;
  87.                         /* bypass any line consisting of white space */
  88.       if ( (file_token = strtok(file_line, delim )) == NULL)
  89.          continue;
  90.       if (file_token[len = strlen(file_token) - 1] != ':') {
  91.          fprintf(stderr, "getf: incorrect file format on %s", file_name);
  92.          exit(1);
  93.       }
  94.       file_token [len] = 0;     /* kill trailing colon */
  95.       last_func = FALSE;      /* set up to detect last func this file */
  96.  
  97.       while ( !eof && !last_func) {    /* loop thru func names this file */
  98.                                        /* last such ends with semicolon */
  99.          if (fgets(func_line, LINE_LEN, funcs_file) == NULL) {
  100.             eof = TRUE;
  101.             break;
  102.          }
  103.                /* bypass any line consisting of white space */
  104.          if ( (func_token = strtok(func_line, delim )) == NULL)
  105.             continue;
  106.          if (func_token [len = strlen(func_token) - 1] == ';') {
  107.             last_func = TRUE;       /* break loop after this one */
  108.             func_token [len] = 0;   /* kill trailing semi-colon */
  109.          }
  110.          if (patn_match(func_name, func_token)) {
  111.             func_choices[num_choices] = strdup(func_token);
  112.             file_choices[num_choices++] = strdup(file_token);
  113.          }
  114.       }  /* while */
  115.    }  /* while */
  116.  
  117.    switch (num_choices) {
  118.       case 0:
  119.          fprintf(stderr, "getf: no match for %s in %s", func_name, file_name);
  120.          exit(1);
  121.       case 1:
  122.          edit(func_choices[0], file_choices[0]);
  123.       default:
  124.          ask_for_file(func_choices, file_choices, num_choices);
  125.    }  /* switch */
  126. }  /* end main() */
  127.  
  128. /* Return TRUE if string "s" matches pattern 'patn',
  129. *  or FALSE if it does not. Allowable wildcards in
  130. *  patn are: ? for one character, % for any string
  131. *  of characters up to the next underscore or end
  132. *  of string, and * for any string of characters up
  133. *  to end of string.
  134. */
  135.  
  136. int patn_match(patn, s)
  137. char *patn;       /* pattern */
  138. char *s;          /* string */
  139. {
  140.  
  141.    for ( ; *patn; patn++) {
  142.       if (!*s) /* if out of s chars, no match unless patn ends with * or & */
  143.          return ((*patn == '*' || *patn == '%') && !*(patn + 1));
  144.       switch(*patn) {
  145.          case '%':
  146.             while (*s != '_' && *s)
  147.                s++;
  148.             break;
  149.          case '*':
  150.             while (*s++)
  151.                ;
  152.             break;
  153.          case '?':
  154.             s++;
  155.             break;
  156.          default:
  157.             if (*s != *patn)
  158.                return FALSE;
  159.             s++;
  160.       }  /* switch */
  161.    }  /* for */
  162.    return *s == 0;
  163. }  /* patn_match() */
  164.  
  165. void ask_for_file(func_choices, file_choices, num_choices)
  166. char *func_choices[], *file_choices[];
  167. unsigned int num_choices;
  168. {
  169.  
  170.    int i;
  171.    char line[LINE_LEN];
  172.  
  173.    while (TRUE) {
  174.       printf( "Which one? (CR to exit)\n");
  175.       for (i = 1; i <= num_choices; i++)
  176.          printf( "\t%3d: %20.20s in % - 30.30s\n", i, func_choices [i - 1],
  177.                                                 file_choices [i - 1]);
  178.       printf(" \nEnter number: ");
  179.       fgets (line, LINE_LEN, stdin);
  180.       if (line[0] == '\n')
  181.          break;
  182.       if ( (i = atoi(line)) < 1 || i > num_choices)
  183.          printf( "Invalid choice:\007\n");
  184.       else
  185.          edit (func_choices [i - 1], file_choices [i - 1]);
  186.    }  /* while */
  187. }  /* end ask_for-file() */
  188.  
  189. void edit(func, file)
  190. char *func, *file;
  191. {
  192.  
  193.          /* execlp will overlay this program with the editor */
  194.    if (num_ctl_patns == 1)
  195.       sprintf (arg1, arg1_ctl, file);
  196.    else
  197.       sprintf (arg1, arg1_ctl, func, file);
  198.    execlp (pgm_name, pgm_name, arg1, NULL);
  199.  
  200.          /* If we're still here, print error message */
  201.    fprintf(stderr, "\ngetf: exec failed");
  202.    exit(1);
  203. }  /* end edit() */
  204.  
  205.